import 'dart:async';
import 'dart:convert' show json;

import 'package:flutter/services.dart';
import 'package:rongcloud_im_plugin/conversation.dart';
import 'package:rongcloud_im_plugin/message.dart';
import 'message_factory.dart';
import 'rc_common_define.dart';
import 'message_content.dart';

class RongcloudImPlugin {
  static final MethodChannel _channel =
      const MethodChannel('rongcloud_im_plugin');

  static void init(String appkey) {
    _channel.invokeMethod(RCMethodKey.Init, appkey);
  }

  static void config(Map conf) {
    _channel.invokeMethod(RCMethodKey.Config, conf);
  }

  static Future<int> connect(String token) async {
    final int code = await _channel.invokeMethod(RCMethodKey.Connect, token);
    return code;
  }

  static void disconnect(bool needPush) {
    _channel.invokeMethod(RCMethodKey.Disconnect, needPush);
  }

  static void updateCurrentUserInfo(
      String userId, String name, String portraitUrl) {
    refreshUserInfo(userId, name, portraitUrl);
  }

  static Future<Message> sendMessage(
      int conversationType, String targetId, MessageContent content) async {
    String jsonStr = content.encode();
    String objName = content.getObjectName();
    Map map = {
      'conversationType': conversationType,
      'targetId': targetId,
      "content": jsonStr,
      "objectName": objName
    };
    Map resultMap = await _channel.invokeMethod(RCMethodKey.SendMessage, map);
    if (resultMap == null) {
      return null;
    }
    String messageString = resultMap["message"];
    Message msg = MessageFactory.instance.string2Message(messageString);
    return msg;
  }

  static Future<List> getHistoryMessage(
      int conversationType, String targetId, int messageId, int count) async {
    Map map = {
      'conversationType': conversationType,
      'targetId': targetId,
      "messageId": messageId,
      "count": count
    };
    List list = await _channel.invokeMethod(RCMethodKey.GetHistoryMessage, map);
    if (list == null) {
      return null;
    }
    List msgList = new List();
    for (String msgStr in list) {
      Message msg = MessageFactory.instance.string2Message(msgStr);
      msgList.add(msg);
    }
    return msgList;
  }

  static Future<List> getConversationList() async {
    List list = await _channel.invokeMethod(RCMethodKey.GetConversationList);
    if (list == null) {
      return null;
    }
    List conList = new List();
    for (String conStr in list) {
      Conversation con = MessageFactory.instance.string2Conversation(conStr);
      conList.add(con);
    }
    return conList;
  }

  static Future<List> getTopConversationList() async {
    List list = await _channel.invokeMethod(RCMethodKey.GetTopConversationList);
    if (list == null) {
      return [];
    }
    List conList = new List();
    for (String conStr in list) {
      Map map = json.decode(conStr);
      conList.add(map["targetId"]);
    }
    return conList;
  }

  static Future<bool> clearConversations(
      int conversationType, String targetId) async {
    Map map = {'conversationType': conversationType, 'targetId': targetId};
    bool rc = await _channel.invokeMethod(RCMethodKey.ClearConversations, map);
    return rc;
  }

  static Future<bool> setConversationToTop(
      int conversationType, String targetId, bool isTop) async {
    Map map = {
      'conversationType': conversationType,
      'targetId': targetId,
      'isTop': isTop
    };
    bool rc =
        await _channel.invokeMethod(RCMethodKey.SetConversationToTop, map);
    return rc;
  }

  static Future<bool> clearMessagesUnreadStatus(
      int conversationType, String targetId) async {
    Map map = {'conversationType': conversationType, 'targetId': targetId};
    bool rc =
        await _channel.invokeMethod(RCMethodKey.ClearMessagesUnreadStatus, map);
    return rc;
  }

  static void joinChatRoom(String targetId, int messageCount) {
    Map map = {"targetId": targetId, "messageCount": messageCount};
    _channel.invokeMethod(RCMethodKey.JoinChatRoom, map);
  }

  static void quitChatRoom(String targetId) {
    Map map = {"targetId": targetId};
    _channel.invokeMethod(RCMethodKey.QuitChatRoom, map);
  }

  // memeberCount 最大 20
  static Future getChatRoomInfo(
      String targetId, int memeberCount, int memberOrder) async {
    if (memeberCount > 20) {
      memeberCount = 20;
    }
    Map map = {
      "targetId": targetId,
      "memeberCount": memeberCount,
      "memberOrder": memberOrder
    };
    Map resultMap =
        await _channel.invokeMethod(RCMethodKey.GetChatRoomInfo, map);
    return MessageFactory.instance.map2ChatRoomInfo(resultMap);
  }

  static void refreshUserInfo(String userId, String name, String portraitUrl) {
    Map map = {'userId': userId, 'name': name, 'portraitUrl': portraitUrl};
    _channel.invokeMethod(RCMethodKey.RefrechUserInfo, map);
  }

  static void setServerInfo(String naviServer, String fileServer) {
    Map map = {"naviServer": naviServer, "fileServer": fileServer};
    _channel.invokeMethod(RCMethodKey.SetServerInfo, map);
  }

  static void setRCNativeMethodCallHandler(
      Future<dynamic> handler(MethodCall call)) {
    _channel.setMethodCallHandler(handler);
  }

  // 加入黑名单
  static Future<bool> addToBlacklist(String userId) async {
    Map map = {'userId': userId};
    bool rs = await _channel.invokeMethod(RCMethodKey.AddToBlacklist, map);
    return rs;
  }

  // 从黑名单移除
  static Future<bool> removeFromBlacklist(String userId) async {
    Map map = {'userId': userId};
    bool rs = await _channel.invokeMethod(RCMethodKey.RemoveFromBlacklist, map);
    return rs;
  }

  // 查询用户是否在黑名单中
  static Future<bool> getBlacklistStatus(String userId) async {
    Map map = {'userId': userId};
    bool rs = await _channel.invokeMethod(RCMethodKey.GetBlacklistStatus, map);
    return rs;
  }

  // 获取黑名单列表
  static Future<List> getBlacklist() async {
    List list = await _channel.invokeMethod(RCMethodKey.GetBlacklist);
    return list;
  }
}
